package com.example.theme_hospital;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

public class HospitalGamePanel extends JPanel implements ActionListener {
    public static final int TILE_WIDTH = 64;
    public static final int TILE_HEIGHT = 32;
    private static final int MAP_WIDTH = 20;
    private static final int MAP_HEIGHT = 20;
    
    // 游戏对象类型
    public static final int EMPTY = 0;
    public static final int GRASS = 1;
    public static final int HOSPITAL_FLOOR = 2;
    public static final int WALL = 3;
    public static final int DOCTOR = 4;
    public static final int PATIENT = 5;
    public static final int PHARMACY = 6;
    public static final int WARD = 7;
    
    // 地图数据
    private int[][] map;
    
    // 建筑物列表
    private List<Building> buildings;
    
    // 视角偏移
    private int cameraX = 0;
    private int cameraY = 0;
    
    // 医生对象
    private Doctor doctor;
    
    // 病人列表
    private List<Patient> patients;
    
    // 游戏时钟
    private Timer gameTimer;
    
    public HospitalGamePanel() {
        initMap();
        initBuildings();
        initDoctor();
        initPatients();
        initGameTimer();
    }
    
    private void initMap() {
        map = new int[MAP_HEIGHT][MAP_WIDTH];
        // 初始化地图数据
        for (int y = 0; y < MAP_HEIGHT; y++) {
            for (int x = 0; x < MAP_WIDTH; x++) {
                // 默认为草地
                map[y][x] = GRASS;
            }
        }
    }
    
    private void initBuildings() {
        buildings = new ArrayList<>();
        // 添加医院建筑
        buildings.add(new Building(HOSPITAL_FLOOR, 5, 4, 11, 3)); // 医院主体
        buildings.add(new Building(WALL, 5, 4, 11, 1)); // 北墙
        buildings.add(new Building(WALL, 5, 6, 11, 1)); // 南墙
        buildings.add(new Building(WALL, 5, 4, 1, 3)); // 西墙
        buildings.add(new Building(WALL, 15, 4, 1, 3)); // 东墙
        
        // 添加药店
        buildings.add(new Building(PHARMACY, 2, 2, 3, 2));
        
        // 添加病房
        buildings.add(new Building(WARD, 15, 15, 3, 2));
        
        // 更新地图数据
        for (Building building : buildings) {
            int type = building.getType();
            int x = building.getX();
            int y = building.getY();
            int width = building.getWidth();
            int height = building.getHeight();
            
            // 根据建筑物类型更新地图
            for (int by = y; by < y + height && by < MAP_HEIGHT; by++) {
                for (int bx = x; bx < x + width && bx < MAP_WIDTH; bx++) {
                    if (type == HOSPITAL_FLOOR || type == PHARMACY || type == WARD) {
                        map[by][bx] = HOSPITAL_FLOOR;
                    } else if (type == WALL) {
                        map[by][bx] = WALL;
                    }
                }
            }
        }
    }
    
    private void initDoctor() {
        // 初始化医生位置在医院内
        doctor = new Doctor(10, 5);
    }
    
    private void initPatients() {
        patients = new ArrayList<>();
        // 添加几个病人在医院外
        patients.add(new Patient(2, 2));
        patients.add(new Patient(17, 3));
        patients.add(new Patient(3, 17));
    }
    
    private void initGameTimer() {
        gameTimer = new Timer(16, this); // 约60 FPS
        gameTimer.start();
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        Graphics2D g2d = (Graphics2D) g.create();
        
        // 绘制等距地图
        renderIsometricMap(g2d);
        
        // 渲染建筑物
        renderBuildings(g2d);
        
        // 渲染医生
        renderDoctor(g2d);
        
        // 渲染病人
        renderPatients(g2d);
        
        g2d.dispose();
    }
    
    private void renderIsometricMap(Graphics2D g) {
        // 等距地图渲染逻辑
        for (int y = 0; y < MAP_HEIGHT; y++) {
            for (int x = 0; x < MAP_WIDTH; x++) {
                // 转换为等距坐标
                int isoX = (x - y) * TILE_WIDTH / 2;
                int isoY = (x + y) * TILE_HEIGHT / 2;
                
                // 应用摄像机偏移
                isoX -= cameraX;
                isoY -= cameraY;
                
                // 屏幕中心对齐
                isoX += getWidth() / 2;
                isoY += getHeight() / 4;
                
                // 绘制地块
                drawTile(g, isoX, isoY, map[y][x]);
            }
        }
    }
    
    private void renderBuildings(Graphics2D g) {
        // 渲染所有建筑物
        for (Building building : buildings) {
            int type = building.getType();
            int x = building.getX();
            int y = building.getY();
            int width = building.getWidth();
            int height = building.getHeight();
            
            // 根据建筑物类型绘制
            for (int by = y; by < y + height && by < MAP_HEIGHT; by++) {
                for (int bx = x; bx < x + width && bx < MAP_WIDTH; bx++) {
                    // 转换为等距坐标
                    int isoX = (bx - by) * TILE_WIDTH / 2;
                    int isoY = (bx + by) * TILE_HEIGHT / 2;
                    
                    // 应用摄像机偏移
                    isoX -= cameraX;
                    isoY -= cameraY;
                    
                    // 屏幕中心对齐
                    isoX += getWidth() / 2;
                    isoY += getHeight() / 4;
                    
                    // 绘制建筑物
                    drawBuilding(g, isoX, isoY, type);
                }
            }
        }
    }
    
    private void renderDoctor(Graphics2D g) {
        // 将医生坐标转换为等距坐标
        int doctorX = doctor.x;
        int doctorY = doctor.y;
        
        int isoX = (doctorX - doctorY) * TILE_WIDTH / 2;
        int isoY = (doctorX + doctorY) * TILE_HEIGHT / 2;
        
        // 应用摄像机偏移
        isoX -= cameraX;
        isoY -= cameraY;
        
        // 屏幕中心对齐
        isoX += getWidth() / 2;
        isoY += getHeight() / 4;
        
        // 绘制医生
        doctor.render(g, isoX, isoY);
    }
    
    private void renderPatients(Graphics2D g) {
        // 渲染所有病人
        for (Patient patient : patients) {
            // 将病人坐标转换为等距坐标
            int patientX = patient.x;
            int patientY = patient.y;
            
            int isoX = (patientX - patientY) * TILE_WIDTH / 2;
            int isoY = (patientX + patientY) * TILE_HEIGHT / 2;
            
            // 应用摄像机偏移
            isoX -= cameraX;
            isoY -= cameraY;
            
            // 屏幕中心对齐
            isoX += getWidth() / 2;
            isoY += getHeight() / 4;
            
            // 绘制病人
            patient.render(g, isoX, isoY);
        }
    }
    
    private void drawTile(Graphics2D g, int x, int y, int tileType) {
        // 根据不同类型使用不同颜色绘制地块
        switch (tileType) {
            case GRASS: // 草地 - 绿色
                g.setColor(Color.GREEN);
                break;
            case HOSPITAL_FLOOR: // 医院地板 - 蓝色
                g.setColor(Color.BLUE);
                break;
            case WALL: // 墙壁 - 灰色
                g.setColor(Color.GRAY);
                break;
            case EMPTY:
            default:
                g.setColor(Color.WHITE);
                break;
        }
        
        // 绘制菱形地块
        int[] xPoints = {x, x + TILE_WIDTH/2, x, x - TILE_WIDTH/2};
        int[] yPoints = {y - TILE_HEIGHT/2, y, y + TILE_HEIGHT/2, y};
        g.fillPolygon(xPoints, yPoints, 4);
        
        // 绘制网格线
        g.setColor(Color.BLACK);
        g.drawPolygon(xPoints, yPoints, 4);
    }
    
    private void drawBuilding(Graphics2D g, int x, int y, int buildingType) {
        // 根据不同类型使用不同颜色绘制建筑物
        switch (buildingType) {
            case HOSPITAL_FLOOR: // 医院地板 - 蓝色
                g.setColor(Color.BLUE);
                break;
            case WALL: // 墙壁 - 灰色
                g.setColor(Color.GRAY);
                break;
            case PHARMACY: // 药店 - 橙色
                g.setColor(Color.ORANGE);
                break;
            case WARD: // 病房 - 紫色
                g.setColor(new Color(128, 0, 128)); // 紫色
                break;
            default:
                return;
        }
        
        // 绘制菱形建筑物
        int[] xPoints = {x, x + TILE_WIDTH/2, x, x - TILE_WIDTH/2};
        int[] yPoints = {y - TILE_HEIGHT/2, y, y + TILE_HEIGHT/2, y};
        g.fillPolygon(xPoints, yPoints, 4);
        
        // 绘制网格线
        g.setColor(Color.BLACK);
        g.drawPolygon(xPoints, yPoints, 4);
    }
    
    // 移动医生
    public void moveDoctor(int dx, int dy) {
        doctor.move(dx, dy, map, MAP_WIDTH, MAP_HEIGHT);
    }
    
    // 诊断最近的病人
    public void diagnosePatient() {
        Patient nearestPatient = findNearestPatient();
        if (nearestPatient != null) {
            doctor.setCurrentPatient(nearestPatient);
        }
    }
    
    // 查找最近的病人
    private Patient findNearestPatient() {
        Patient nearest = null;
        double minDistance = Double.MAX_VALUE;
        
        for (Patient patient : patients) {
            // 计算医生与病人的距离
            double dx = patient.x - doctor.x;
            double dy = patient.y - doctor.y;
            double distance = Math.sqrt(dx * dx + dy * dy);
            
            // 检查是否在诊断范围内（距离小于2）
            if (distance < 2 && distance < minDistance) {
                minDistance = distance;
                nearest = patient;
            }
        }
        
        return nearest;
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        // 游戏主循环更新
        doctor.update();
        
        // 更新所有病人
        for (Patient patient : patients) {
            patient.update(map, MAP_WIDTH, MAP_HEIGHT);
        }
        
        // 保持医生在屏幕中心
        cameraX = (doctor.x - doctor.y) * TILE_WIDTH / 2;
        cameraY = (doctor.x + doctor.y) * TILE_HEIGHT / 2;
        
        repaint();
    }
}